﻿using Ionic.Zip;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.IO;
using System.Web.UI;
using Marbles.Core.Connectors;
using System.Data;

namespace Marbles.Core.Modules
{
    public static class ModuleInstallationManager
    {
        public static bool UnInstall(string id, Pages.Page Page)
        {
            string _modulepath = HttpContext.Current.Server.MapPath(Settings.SettingsManager.ModuleInstallationDirectory);
            string controlname = string.Empty;
            string installfolder = string.Empty;            
            DataConnection dbc = new DataConnection();
            Command cmd = new Command("SELECT installfolder, controlname FROM modules WHERE moduleid = @moduleid");
            cmd.AddParameter("@moduleid", id);
            DataTable dt = dbc.FetchDataTable(cmd);

            if (dt.Rows.Count <= 0) { return false; }

            installfolder = dt.Rows[0]["installfolder"].ToString();
            controlname = dt.Rows[0]["controlname"].ToString();

            Control ctl = Page.LoadControl(Settings.SettingsManager.ModuleInstallationDirectory + "/" + installfolder + "/" + controlname);
            if (ctl == null) { return false; }
            ((ModuleBase)ctl).UnInstall();
            ctl.Dispose();

            cmd = new Command("DELETE FROM modules WHERE moduleid = @moduleid");
            cmd.AddParameter("@moduleid", id);
            dbc.ExecuteCommand(cmd);
            return true;
        }

        public static Control LoadModule(string id, Pages.Page Page)
        {
            string controlname = string.Empty;
            string installfolder = string.Empty;
            DataConnection dbc = new DataConnection();
            Command cmd = new Command("SELECT installfolder, controlname FROM modules WHERE moduleid = @moduleid");
            cmd.AddParameter("@moduleid", id);
            DataTable dt = dbc.FetchDataTable(cmd);

            if (dt.Rows.Count <= 0) { return null; }

            installfolder = dt.Rows[0]["installfolder"].ToString();
            controlname = dt.Rows[0]["controlname"].ToString();

            Control ctl = Page.LoadControl(Settings.SettingsManager.ModuleInstallationDirectory + "/" + installfolder + "/" + controlname);
            return ctl;
        }

        public static string Install(Stream stream, string installfolder, Pages.Page Page)
        {
            string _modulepath = HttpContext.Current.Server.MapPath(Settings.SettingsManager.ModuleInstallationDirectory);
            string id = Guid.NewGuid().ToString();
            string controlname = string.Empty;
            string installPath = Path.Combine(_modulepath, installfolder);
            if (!Directory.Exists(installPath)) { Directory.CreateDirectory(installPath); }

            using (ZipFile zip = ZipFile.Read(stream))
            {
                foreach (ZipEntry e in zip)
                {
                    if (System.IO.Path.GetExtension(e.FileName).ToLower() == ".ascx")
                    {
                        FileInfo info = new FileInfo(e.FileName);
                        controlname = info.Name;
                    }

                    e.Extract(installPath, ExtractExistingFileAction.OverwriteSilently);
                }
            }

            if (!string.IsNullOrEmpty(controlname))
            {
                Control ctl = Page.LoadControl(Settings.SettingsManager.ModuleInstallationDirectory + "/" + installfolder + "/" + controlname);
                if (ctl == null) { return string.Empty; }
                ((ModuleBase)ctl).Install();
                DataConnection dbc = new DataConnection();
                Command cmd = new Command("INSERT INTO modules (moduleid, title, author, installfolder, controlname) VALUES (@moduleid, @title, @author, @installfolder, @controlname");
                cmd.AddParameter("@moduleid", id);
                cmd.AddParameter("@title", ((ModuleBase)ctl).ModuleName);
                cmd.AddParameter("@author", ((ModuleBase)ctl).ModuleAuthor);
                cmd.AddParameter("@installfolder", installfolder);
                cmd.AddParameter("@controlname", controlname);
                dbc.ExecuteCommand(cmd);
                ctl.Dispose();
            }

            return id;
        }

        public static void Install(string filename, string installfolder, Pages.Page Page)
        {
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            Install(fs, installfolder, Page);
            fs.Flush();
            fs.Close();
        }
    }
}
